const crypto = require('crypto'); // Node.js 内置模块，无需安装
const bcrypt = require('bcryptjs');

const KEY = Buffer.from('1234567812345678', 'utf8')  // 16 字节
const IV = Buffer.from('8765432187654321', 'utf8')   // 16 字节

/**
 * 加密工具模块
 * 提供密码加密、验证和通用加密功能
 */
class Encryption {
  /**
   * 生成盐值
   * @param {number} rounds 盐值轮数，默认10
   * @returns {string} 盐值
   */
  static generateSalt(rounds = 10) {
    return bcrypt.genSaltSync(rounds);
  }

  /**
   * 加密密码
   * @param {string} password 明文密码
   * @param {string|number} salt 盐值或轮数
   * @returns {string} 加密后的密码
   */
  static hashPassword(password, salt = 10) {
    if (typeof salt === 'number') {
      salt = this.generateSalt(salt);
    }
    return bcrypt.hashSync(password, salt);
  }

  /**
   * 验证密码
   * @param {string} password 明文密码
   * @param {string} hashedPassword 加密后的密码
   * @returns {boolean} 是否匹配
   */
  static comparePassword(password, hashedPassword) {
    return bcrypt.compareSync(password, hashedPassword);
  }

  /**
   * 生成随机令牌
   * @param {number} length 令牌长度，默认32
   * @returns {string} 随机令牌
   */
  static generateToken(length = 32) {
    return crypto.randomBytes(length).toString('hex');
  }

  /**
   * 使用SHA256哈希字符串
   * @param {string} data 要哈希的数据
   * @returns {string} 哈希值
   */
  static sha256(data) {
    return crypto.createHash('sha256').update(data).digest('hex');
  }

  /**
   * 使用HMAC-SHA256签名数据
   * @param {string} data 要签名的数据
   * @param {string} secret 密钥
   * @returns {string} 签名
   */
  static hmacSha256(data, secret) {
    return crypto.createHmac('sha256', secret).update(data).digest('hex');
  }

  /**
   * 解密
   * @param {*} cipherText 
   * @returns 
   */
  static decryptAES(cipherText) {
    const decipher = crypto.createDecipheriv('aes-128-cbc', KEY, IV)
    let decrypted = decipher.update(cipherText, 'base64', 'utf8')
    decrypted += decipher.final('utf8')
    return decrypted
  }

  /**
   * 加密
   * @param {*} text 
   * @returns 
   */
  static encryptAES(text) {
    const cipher = crypto.createCipheriv('aes-128-cbc', KEY, IV)
    let encrypted = cipher.update(text, 'utf8', 'base64')
    encrypted += cipher.final('base64')
    return encrypted
  }
}

module.exports = Encryption;